package com.bwie.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bwie.es.EsProd;
import com.bwie.mapper.ProdAttaMapper;
import com.bwie.mapper.ProdInfoMapper;
import com.bwie.poi.StringUtils;
import com.bwie.pojo.ProdAtta;
import com.bwie.pojo.ProdInfo;
import com.bwie.service.ProdAttaService;
import com.bwie.utils.R;
import com.bwie.vo.ProdPageVo;
import io.jsonwebtoken.Jwts;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;

import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.pojo.Prod;
import com.bwie.mapper.ProdMapper;
import com.bwie.service.ProdService;
import org.springframework.transaction.annotation.Transactional;
import sun.awt.image.PNGImageDecoder;

import javax.servlet.http.HttpServletRequest;

@Service
public class ProdServiceImpl extends ServiceImpl<ProdMapper, Prod> implements ProdService{
    @Autowired
    ProdMapper prodMapper;

    @Autowired
    HttpServletRequest request;

    @Autowired
    ProdAttaMapper prodAttaMapper;

    @Autowired
    ProdInfoMapper prodInfoMapper;

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public R getProdList(ProdPageVo prodPageVo) {
        Page<Prod> page = new Page<>(prodPageVo.getPageNum(), prodPageVo.getPageSize());
        Page<Prod> prodPage = prodMapper.selectProdList(page, prodPageVo.getKeyWord());

        return R.ok().setData(prodPage);
    }

    @Override
    public R addProdList(Prod prod) {
        QueryWrapper<Prod> wrapper = new QueryWrapper<>();
        Prod prod1 = prodMapper.selectOne(wrapper.lambda().eq(Prod::getProdName, prod.getProdName()).or().eq(Prod::getProdSpu,prod.getProdSpu()));
        if(prod1!=null){
            return R.error().setMsg("名称已存在");
        }


        String token = request.getHeader("token");
        String userName = Jwts.parser().setSigningKey("bwie").parseClaimsJws(token).getBody().get("userName", String.class);
        prod.setCreateBy(userName);
        prod.setCreateTime(new Date());
        prod.setProdStatus(0);

        prodMapper.insert(prod);
        return R.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R addProdAtta(ProdAtta prodAtta) {
        Prod prod = prodMapper.selectById(prodAtta.getProdId());
        if(prod==null){
            return R.error().setMsg("商品不存在");
        }
        prodAttaMapper.delete(new QueryWrapper<ProdAtta>().lambda().eq(ProdAtta::getProdId,prodAtta.getProdId()));
        prodAttaMapper.insert(prodAtta);

        return R.ok();
    }

    @Override
    public R BatchDelete(List<Integer> prodIds) {
        prodMapper.deleteBatchIds(prodIds);
        //删除商品附件
        prodAttaMapper.delete(new QueryWrapper<ProdAtta>().lambda().in(ProdAtta::getProdId,prodIds));
        return R.ok();
    }

    @Override
    public R deleteProd(Integer prodId) {
        Prod prod = prodMapper.selectById(prodId);
        if(prod==null){
            return R.error().setMsg("商品不存在");
        }

        prodMapper.deleteById(prodId);
        return R.ok();
    }

    @Override
    public R prodInfoList() {
        List<ProdInfo> prodInfos = prodInfoMapper.selectList(null);

        return R.ok().setData(prodInfos);
    }

    @Override
    public R getEsshoppingList(ProdPageVo prodPageVo) {
        Integer pageNum=0;
        if(prodPageVo.getPageNum()>0){
            pageNum=prodPageVo.getPageNum()-1;
        }
        PageRequest pageRequest = PageRequest.of(pageNum, prodPageVo.getPageSize());
        //构造多天剑查询
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //
        if(StringUtils.isNotEmpty(prodPageVo.getKeyWord())){
            boolQueryBuilder.should(QueryBuilders.matchQuery("prodName",prodPageVo.getKeyWord()));
            boolQueryBuilder.should(QueryBuilders.matchQuery("brandName",prodPageVo.getKeyWord()));
        }
        //状态搜索
        if(StringUtils.isNotEmpty(prodPageVo.getStatus())){
            boolQueryBuilder.must(QueryBuilders.termQuery("prodStatus",prodPageVo.getStatus()));
        }
        //根据价格区间查询
        if(StringUtils.isNotEmpty(prodPageVo.getBeginTime())&& StringUtils.isNotEmpty(prodPageVo.getEndTime())){
            boolQueryBuilder.must(QueryBuilders.rangeQuery("createTime")
                    .format("yyyy-MM-dd HH:mm:ss")
                    .timeZone("GMT+8")
                    .from(prodPageVo.getBeginTime())
                    .to(prodPageVo.getEndTime()));
        }

        //添加高亮

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("prodName").field("brandName")
                .preTags("<font color='red'>").postTags("</font>");

        //排序
        FieldSortBuilder prodId = SortBuilders.fieldSort("prodId").order(SortOrder.ASC);

        //查询
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder)
                .withPageable(pageRequest)
                .withSort(prodId)
                .withHighlightBuilder(highlightBuilder);
        SearchHits<EsProd> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), EsProd.class);


        //4读取数据
        long totalHits = search.getTotalHits();
        ArrayList<EsProd> esProds = new ArrayList<>();

        for (SearchHit<EsProd> searchHit : search.getSearchHits()) {
            EsProd esProd = searchHit.getContent();


            //读取高亮信息
            List<String> prodName = searchHit.getHighlightField("prodName");
            if(prodName!=null && prodName.size()>0){
                esProd.setProdName(prodName.get(0));
            }

            List<String> brandNames = searchHit.getHighlightField("brandName");
            if(brandNames!=null && brandNames.size()>0) {
                esProd.setBrandName(brandNames.get(0));
            }

            esProds.add(esProd);
        }

        //返回数据
        HashMap<String, Object> map = new HashMap<>(2);
        map.put("total",totalHits);
        map.put("records",esProds);
        return R.ok().setData(map);
    }

    @Override
    public void createIndex() {
        IndexOperations indexOps = elasticsearchRestTemplate.indexOps(EsProd.class);
        boolean exists = indexOps.exists();
        if(exists){
            indexOps.delete();
        }
        indexOps.create();

        Document mapping = indexOps.createMapping();
        indexOps.putMapping(mapping);

        List<EsProd> prodList = prodMapper.getselectProdList(null);
        for (EsProd esProd : prodList) {
            EsProd bean = BeanUtil.toBean(esProd, EsProd.class);
            elasticsearchRestTemplate.save(bean);
        }

        System.out.println("创建成功");
    }


}
